/**
 * author      : dormi330
 * date        : 2018/6/24
 * project     : mybatis
 * description : 领域行为: 创建订单
 */

package com.deep.trade.domain.order;

import com.deep.trade.adaptor.required.MemberAddress;
import com.deep.trade.adaptor.required.member.Member;
import com.deep.trade.order.dto.SkuAndQty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CommandPlaceOrder {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    TradeOrderFactory tradeOrderFactory;

    /**
     * 新建订单
     *
     * @param member        会员
     * @param address       地址
     * @param skuAndQtyList sku列表
     * @throws Exception
     */
    @Transactional
    public String placeOrder(
            Member member,
            MemberAddress address,
            String remark,
            List<SkuAndQty> skuAndQtyList,
            boolean isAudit
    ) throws Exception {
        OrderSummary orderSummary = splitOrder(member, address, remark, skuAndQtyList);

        // 如果不审核, 直接审核通过
        if (!isAudit) {
            for (TradeOrder tradeOrder : orderSummary.getTradeOrderList()) {
                tradeOrder.audit(true, null);
            }
        }

        // save
        saveNewOrder(orderSummary);
        return orderSummary.getId();

        // TODO 订单创建之后, 如果有支付超时限制, 则启动
    }

    public OrderSummary splitOrder(Member member, MemberAddress address, String remark, List<SkuAndQty> skuAndQtyList) throws Exception {
        return splitOrderStep1(member, address, remark, skuAndQtyList);
    }

    /**
     * 拆单第一步, 按照店铺进行拆单, 不计算优惠
     * 后续应该还有步骤
     *
     * @param member        会员信息
     * @param address       地址信息
     * @param remark        备注
     * @param skuAndQtyList sku列表
     * @throws Exception
     */
    private OrderSummary splitOrderStep1(
            Member member,
            MemberAddress address,
            String remark,
            List<SkuAndQty> skuAndQtyList
    ) throws Exception {
        // 缓存
        Map<String, TradeOrder> tradeOrderMap = new HashMap<>();

        // step10, 根据skuAndQtyList, 得到所有tradeOrderSkuList
        List<TradeOrderSku> tradeOrderSkuList = tradeOrderFactory.tradeOrderSku(skuAndQtyList, member, address);

        // step20, 根据tradeOrderSkuList, 整理得到所有 TradeOrder, 已经包含了地址信息
        for (TradeOrderSku tradeOrderSku : tradeOrderSkuList) {
            TradeOrder tradeOrder = tradeOrderMap.get(tradeOrderSku.getShopId());
            if (null == tradeOrder) {
                tradeOrder = tradeOrderFactory.tradeOrderFromSku(tradeOrderSku, member, remark);
                // tradeOrder 完善 地址信息
                tradeOrder.setDeliveryAddress(tradeOrderFactory.deliveryAddressWithoutTradeOrderId(member.getId(), address));
                tradeOrderMap.put(tradeOrderSku.getShopId(), tradeOrder);
            }
            tradeOrder.addTradeOrderSku(tradeOrderSku);
        }

        tradeOrderMap.values().forEach(TradeOrder::calculateMoney);

        // step40, 创建 OrderSummary
        OrderSummary orderSummary = tradeOrderFactory.createOrderSummary(member);
        for (TradeOrder tradeOrder : tradeOrderMap.values()) {
            orderSummary.addTradeOrder(tradeOrder);
        }
        orderSummary.calculateMoney();

        // 返回结果
        return orderSummary;
    }


    private void saveNewOrder(OrderSummary orderSummary) throws Exception {
        orderRepository.addOrderSummary(orderSummary);
        orderSummary.getTradeOrderList().forEach(tradeOrder -> {
            orderRepository.addTradeOrder(tradeOrder);
            orderRepository.addDeliveryAddress(tradeOrder.getDeliveryAddress());
            tradeOrder.getSkuList().forEach(tradeOrderSku -> {
                orderRepository.addOrderSku(tradeOrderSku);
            });
        });
    }

}
